package com.king.util.ids;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

import com.king.util.exception.KingException;

import lombok.extern.slf4j.Slf4j;

/**
 * 6位长度的ID工具
 * 
 * @author king
 * @date 2025年7月17日-13:47:14
 */
@Slf4j
public class IDS {

	private static Done done;

	private final static String STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

	/**
	 * 池
	 */
	private final static Map<String, Set<String>> POOL = new HashMap<String, Set<String>>();

	private final static Map<String, BatchPredicate<Set<String>>> cmp = new HashMap<>();

//	public static void main(String[] args) throws KingException {
//		for (int i = 0; i < 2; i++) {
//			String s = IDS.build("king", (d) -> {
//				// 拿到生成随机数数据，区数据库查询，并返回查到的,模拟返回2个数
//				return Set.of(d.iterator().next());
//			}).len(3).get("king");
//			System.out.println(s);
//		}
//	}

	/**
	 * 获取ID，但须提前调用过build，配置过对比函数，否则无效
	 * 
	 * @param group
	 * @return
	 * @author king
	 * @throws KingException
	 * @date 2025年7月17日-15:36:51
	 */
	public static String get(String group) throws KingException {
		return IDS.done.get(group);
	}

	public static Done build(String group, BatchPredicate<Set<String>> cmp) {
		if (IDS.cmp.get(group) == null) {
			IDS.cmp.put(group, cmp);
		}
		if (IDS.done == null) {
			IDS.done = new IDS().new Done(group);
		}
		return IDS.done;
	}

	class Done {
		private String groupCode;
		private int len = 6;

		private int min = 3;

		private int max = 10;

		public Done(String groupCode) {
			this.groupCode = groupCode;
		}

		public Done len(int len) {
			this.len = len;
			return this;
		}

		public String get(String groupCode) throws KingException {
			Set<String> p = POOL.get(groupCode);
			if (p == null) {
				p = new HashSet<>();
				POOL.put(groupCode, p);
			}
			if (p.size() < min) {
				createRandom(p);
			}
			String r = p.iterator().next();
			p.remove(r);
			return r;
		}

		/**
		 * 生成配置长度，和有限的随机数
		 * 
		 * @param list
		 * @author king
		 * @throws KingException
		 * @date 2025年7月17日-14:17:32
		 */
		private void createRandom(Set<String> list) throws KingException {
			log.info("补充池");
			StringBuilder sb = new StringBuilder();
			Set<String> tmp = new HashSet<>();
			while (tmp.size() + list.size() < max) {
				sb.setLength(0);
				for (int i = 0; i < len; i++) {
					sb.append(STR.charAt(ThreadLocalRandom.current().nextInt(STR.length())));
				}
				tmp.add(sb.toString());
			}
			if (cmp == null) {
				KingException.build("须调用过IDS.builder，初始化比较器");
			}
			Set<String> r = cmp.get(groupCode).done(tmp);
			if (r != null && r.size() != 0) {
				log.info("有重复：{}", r);
				tmp.removeAll(r);
			}
			list.addAll(tmp);
			if (list.size() < max) {
				createRandom(list);
			}
		}
	}
}

